package com.zenithmind.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.chat.mapper.ChatMessageMediaMapper;
import com.zenithmind.chat.pojo.entity.ChatMessageMedia;
import com.zenithmind.chat.pojo.dto.ChatMessageMediaDTO;
import com.zenithmind.chat.pojo.vo.ChatMessageMediaVO;
import com.zenithmind.chat.service.ChatMessageMediaService;
import com.zenithmind.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 消息媒体文件服务实现类 - 遵循单一职责原则
 * 只负责消息媒体文件的业务逻辑处理
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatMessageMediaServiceImpl extends ServiceImpl<ChatMessageMediaMapper, ChatMessageMedia> 
        implements ChatMessageMediaService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String uploadMedia(ChatMessageMediaDTO dto, String userId) {
        if (!dto.isValid()) {
            throw new BusinessException("媒体文件信息不完整");
        }
        
        ChatMessageMedia media = new ChatMessageMedia();
        media.setMessageId(dto.getMessageId());
        media.setFileName(dto.getFileName());
        media.setMediaUrl(dto.getFileUrl());
        media.setFileSize(dto.getFileSize());
        media.setMimeType(dto.getMimeType());
        media.setThumbnailUrl(dto.getThumbnailUrl());
        media.setWidth(dto.getWidth());
        media.setHeight(dto.getHeight());
        media.setDuration(dto.getDuration());
        media.setStoragePath(dto.getFilePath());
        media.setExtraInfo(dto.getExtraInfo());
        media.setUploadStatus(1); // 默认上传成功
        media.setCreateTime(LocalDateTime.now());
        media.setUpdateTime(LocalDateTime.now());
        
        save(media);
        
        log.info("上传媒体文件成功，文件ID: {}, 消息ID: {}, 上传者: {}", 
                media.getId(), dto.getMessageId(), userId);
        
        return media.getId();
    }

    @Override
    public List<ChatMessageMediaVO> getMediaByMessageId(String messageId) {
        if (messageId == null || messageId.trim().isEmpty()) {
            throw new BusinessException("消息ID不能为空");
        }
        
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getMessageId, messageId)
                   .eq(ChatMessageMedia::getIsDeleted, 0)
                   .orderByAsc(ChatMessageMedia::getCreateTime);
        
        List<ChatMessageMedia> mediaList = list(queryWrapper);
        return mediaList.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public ChatMessageMediaVO getMediaById(String mediaId, String userId) {
        if (mediaId == null || mediaId.trim().isEmpty()) {
            throw new BusinessException("媒体文件ID不能为空");
        }
        
        ChatMessageMedia media = getById(mediaId);
        if (media == null || media.getIsDeleted() == 1) {
            throw new BusinessException("媒体文件不存在");
        }
        
        // 检查访问权限
        if (!checkMediaAccess(mediaId, userId)) {
            throw new BusinessException("无权限访问该媒体文件");
        }
        
        return convertToVO(media);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteMedia(String mediaId, String userId) {
        if (mediaId == null || mediaId.trim().isEmpty()) {
            throw new BusinessException("媒体文件ID不能为空");
        }
        
        ChatMessageMedia media = getById(mediaId);
        if (media == null || media.getIsDeleted() == 1) {
            throw new BusinessException("媒体文件不存在");
        }

        // 检查删除权限
        if (!checkMediaAccess(mediaId, userId)) {
            throw new BusinessException("无权限删除该媒体文件");
        }

        // 逻辑删除
        media.setIsDeleted(1);
        media.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(media);
        
        if (result) {
            log.info("删除媒体文件成功，文件ID: {}, 操作者: {}", mediaId, userId);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteMedia(List<String> mediaIds, String userId) {
        if (mediaIds == null || mediaIds.isEmpty()) {
            throw new BusinessException("媒体文件ID列表不能为空");
        }
        
        for (String mediaId : mediaIds) {
            deleteMedia(mediaId, userId);
        }
        
        log.info("批量删除媒体文件成功，数量: {}, 操作者: {}", mediaIds.size(), userId);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteMediaByMessageId(String messageId, String userId) {
        if (messageId == null || messageId.trim().isEmpty()) {
            throw new BusinessException("消息ID不能为空");
        }
        
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getMessageId, messageId)
                   .eq(ChatMessageMedia::getIsDeleted, 0);
        
        List<ChatMessageMedia> mediaList = list(queryWrapper);
        
        for (ChatMessageMedia media : mediaList) {
            media.setIsDeleted(1);
            media.setUpdateTime(LocalDateTime.now());
            updateById(media);
        }
        
        log.info("删除消息的所有媒体文件成功，消息ID: {}, 数量: {}, 操作者: {}", 
                messageId, mediaList.size(), userId);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateMedia(String mediaId, ChatMessageMediaDTO dto, String userId) {
        if (mediaId == null || mediaId.trim().isEmpty()) {
            throw new BusinessException("媒体文件ID不能为空");
        }
        
        ChatMessageMedia media = getById(mediaId);
        if (media == null || media.getIsDeleted() == 1) {
            throw new BusinessException("媒体文件不存在");
        }
        
        // 检查修改权限
        if (!checkMediaAccess(mediaId, userId)) {
            throw new BusinessException("无权限修改该媒体文件");
        }
        
        // 更新媒体信息
        if (dto.getFileName() != null) {
            media.setFileName(dto.getFileName());
        }
        if (dto.getExtraInfo() != null) {
            media.setExtraInfo(dto.getExtraInfo());
        }
        
        media.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(media);
        
        if (result) {
            log.info("更新媒体文件成功，文件ID: {}, 操作者: {}", mediaId, userId);
        }
        
        return result;
    }

    @Override
    public List<ChatMessageMediaVO> getUserMediaList(String userId, String mediaType, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getIsDeleted, 0)
                   .orderByDesc(ChatMessageMedia::getCreateTime);
        
        if (mediaType != null && !mediaType.trim().isEmpty()) {
            queryWrapper.like(ChatMessageMedia::getMimeType, mediaType);
        }
        
        Page<ChatMessageMedia> page = new Page<>(pageNum != null ? pageNum : 1, pageSize != null ? pageSize : 20);
        Page<ChatMessageMedia> result = page(page, queryWrapper);
        
        return result.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public List<ChatMessageMediaVO> getGroupMediaList(String groupId, String mediaType, Integer pageNum, Integer pageSize) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new BusinessException("群组ID不能为空");
        }

        // 通过消息表关联查询群组的媒体文件
        // 这里简化处理，实际应该通过JOIN查询
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getIsDeleted, 0)
                   .orderByDesc(ChatMessageMedia::getCreateTime);

        if (mediaType != null && !mediaType.trim().isEmpty()) {
            queryWrapper.like(ChatMessageMedia::getMimeType, mediaType);
        }

        // TODO: 添加群组ID关联查询条件
        // queryWrapper.in(ChatMessageMedia::getMessageId, messageIdsFromGroup);

        Page<ChatMessageMedia> page = new Page<>(pageNum != null ? pageNum : 1, pageSize != null ? pageSize : 20);
        Page<ChatMessageMedia> result = page(page, queryWrapper);

        return result.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public List<ChatMessageMediaVO> searchMedia(String keyword, String mediaType, String userId, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getIsDeleted, 0)
                   .and(wrapper -> wrapper.like(ChatMessageMedia::getFileName, keyword)
                                         .or()
                                         .like(ChatMessageMedia::getExtraInfo, keyword))
                   .orderByDesc(ChatMessageMedia::getCreateTime);

        if (mediaType != null && !mediaType.trim().isEmpty()) {
            queryWrapper.like(ChatMessageMedia::getMimeType, mediaType);
        }
        
        Page<ChatMessageMedia> page = new Page<>(pageNum != null ? pageNum : 1, pageSize != null ? pageSize : 20);
        Page<ChatMessageMedia> result = page(page, queryWrapper);
        
        return result.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public String getDownloadUrl(String mediaId, String userId) {
        ChatMessageMediaVO media = getMediaById(mediaId, userId);
        return media.getFileUrl();
    }

    @Override
    public String getPreviewUrl(String mediaId, String userId) {
        ChatMessageMediaVO media = getMediaById(mediaId, userId);
        return media.getThumbnailUrl() != null ? media.getThumbnailUrl() : media.getFileUrl();
    }

    @Override
    public Boolean checkMediaAccess(String mediaId, String userId) {
        if (mediaId == null || mediaId.trim().isEmpty() || userId == null || userId.trim().isEmpty()) {
            return false;
        }

        ChatMessageMedia media = getById(mediaId);
        if (media == null || media.getIsDeleted() == 1) {
            return false;
        }

        // 简化的权限检查逻辑
        // 实际应该检查用户是否在相关群组中，或者是否为文件上传者
        return true;
    }

    @Override
    public Object getUserMediaStatistics(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            return new Object();
        }

        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getIsDeleted, 0);

        long totalCount = count(queryWrapper);
        long totalSize = list(queryWrapper).stream()
                                          .mapToLong(media -> media.getFileSize() != null ? media.getFileSize() : 0)
                                          .sum();

        return new Object() {
            public long getTotalCount() { return totalCount; }
            public long getTotalSize() { return totalSize; }
            public String getFormattedSize() {
                return formatFileSize(totalSize);
            }

            private String formatFileSize(long size) {
                if (size <= 0) return "0 B";
                String[] units = {"B", "KB", "MB", "GB", "TB"};
                int unitIndex = 0;
                double fileSize = size;
                while (fileSize >= 1024 && unitIndex < units.length - 1) {
                    fileSize /= 1024;
                    unitIndex++;
                }
                return String.format("%.1f %s", fileSize, units[unitIndex]);
            }
        };
    }

    @Override
    public Object getGroupMediaStatistics(String groupId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            return new Object();
        }

        // 简化实现，实际应该通过消息关联查询
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getIsDeleted, 0);

        long totalCount = count(queryWrapper);
        long totalSize = list(queryWrapper).stream()
                                          .mapToLong(media -> media.getFileSize() != null ? media.getFileSize() : 0)
                                          .sum();

        return new Object() {
            public long getTotalCount() { return totalCount; }
            public long getTotalSize() { return totalSize; }
            public String getFormattedSize() {
                return formatFileSize(totalSize);
            }

            private String formatFileSize(long size) {
                if (size <= 0) return "0 B";
                String[] units = {"B", "KB", "MB", "GB", "TB"};
                int unitIndex = 0;
                double fileSize = size;
                while (fileSize >= 1024 && unitIndex < units.length - 1) {
                    fileSize /= 1024;
                    unitIndex++;
                }
                return String.format("%.1f %s", fileSize, units[unitIndex]);
            }
        };
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer cleanupExpiredMedia(Integer retentionDays) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(retentionDays);
        
        LambdaQueryWrapper<ChatMessageMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessageMedia::getIsDeleted, 0)
                   .lt(ChatMessageMedia::getCreateTime, expireTime);
        
        List<ChatMessageMedia> expiredMedia = list(queryWrapper);
        
        for (ChatMessageMedia media : expiredMedia) {
            media.setIsDeleted(1);
            media.setUpdateTime(LocalDateTime.now());
            updateById(media);
        }
        
        log.info("清理过期媒体文件完成，清理数量: {}", expiredMedia.size());
        
        return expiredMedia.size();
    }

    @Override
    public Boolean compressMedia(String mediaId, Integer quality, String userId) {
        // TODO: 实现媒体压缩逻辑
        return true;
    }

    @Override
    public String generateThumbnail(String mediaId, Integer width, Integer height, String userId) {
        // TODO: 实现缩略图生成逻辑
        return "";
    }

    @Override
    public Boolean convertMediaFormat(String mediaId, String targetFormat, String userId) {
        // TODO: 实现格式转换逻辑
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> batchUploadMedia(List<ChatMessageMediaDTO> dtoList, String userId) {
        return dtoList.stream()
                     .map(dto -> uploadMedia(dto, userId))
                     .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String copyMedia(String sourceMediaId, String targetMessageId, String userId) {
        ChatMessageMedia sourceMedia = getById(sourceMediaId);
        if (sourceMedia == null || sourceMedia.getIsDeleted() == 1) {
            throw new BusinessException("源媒体文件不存在");
        }
        
        ChatMessageMedia newMedia = new ChatMessageMedia();
        // 复制所有属性
        newMedia.setMessageId(targetMessageId);
        newMedia.setFileName(sourceMedia.getFileName());
        newMedia.setStoragePath(sourceMedia.getStoragePath());
        newMedia.setMediaUrl(sourceMedia.getMediaUrl());
        newMedia.setFileSize(sourceMedia.getFileSize());
        newMedia.setMimeType(sourceMedia.getMimeType());
        newMedia.setThumbnailUrl(sourceMedia.getThumbnailUrl());
        newMedia.setWidth(sourceMedia.getWidth());
        newMedia.setHeight(sourceMedia.getHeight());
        newMedia.setDuration(sourceMedia.getDuration());
        newMedia.setExtraInfo(sourceMedia.getExtraInfo());
        newMedia.setUploadStatus(sourceMedia.getUploadStatus());
        newMedia.setCreateTime(LocalDateTime.now());
        newMedia.setUpdateTime(LocalDateTime.now());
        
        save(newMedia);
        
        log.info("复制媒体文件成功，源文件ID: {}, 新文件ID: {}, 操作者: {}", 
                sourceMediaId, newMedia.getId(), userId);
        
        return newMedia.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean moveMedia(String mediaId, String targetMessageId, String userId) {
        ChatMessageMedia media = getById(mediaId);
        if (media == null || media.getIsDeleted() == 1) {
            throw new BusinessException("媒体文件不存在");
        }
        
        String oldMessageId = media.getMessageId();
        media.setMessageId(targetMessageId);
        media.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(media);
        
        if (result) {
            log.info("移动媒体文件成功，文件ID: {}, 从消息: {} 到消息: {}, 操作者: {}", 
                    mediaId, oldMessageId, targetMessageId, userId);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setMediaAccess(String mediaId, String accessLevel, String userId) {
        ChatMessageMedia media = getById(mediaId);
        if (media == null || media.getIsDeleted() == 1) {
            throw new BusinessException("媒体文件不存在");
        }
        
        // 将访问级别信息存储在extraInfo中
        media.setExtraInfo(accessLevel);
        media.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(media);
        
        if (result) {
            log.info("设置媒体文件访问权限成功，文件ID: {}, 访问级别: {}, 操作者: {}", 
                    mediaId, accessLevel, userId);
        }
        
        return result;
    }

    @Override
    public Object getMediaMetadata(String mediaId, String userId) {
        ChatMessageMediaVO media = getMediaById(mediaId, userId);
        // TODO: 返回详细的元数据信息
        return media;
    }

    /**
     * 转换为VO
     */
    private ChatMessageMediaVO convertToVO(ChatMessageMedia media) {
        ChatMessageMediaVO vo = new ChatMessageMediaVO();
        vo.setId(media.getId());
        vo.setMessageId(media.getMessageId());
        vo.setMediaType(media.getMimeType()); // 使用mimeType作为mediaType
        vo.setFileName(media.getFileName());
        vo.setFilePath(media.getStoragePath());
        vo.setFileUrl(media.getMediaUrl());
        vo.setFileSize(media.getFileSize());
        vo.setMimeType(media.getMimeType());
        vo.setThumbnailUrl(media.getThumbnailUrl());
        vo.setWidth(media.getWidth());
        vo.setHeight(media.getHeight());
        vo.setDuration(media.getDuration());
        vo.setExtraInfo(media.getExtraInfo());
        vo.setCreateTime(media.getCreateTime());
        vo.setUpdateTime(media.getUpdateTime());
        return vo;
    }
}
